#include "glob.h"

/*
 *
 * Shared Memory Stuff
 *
 * */

int init_share (sharedmem ** sm) {
	const char * temp = "0000";
	int i;
	/* initialize shared memory and semaphore structures*/
	(*sm) = malloc(sizeof(sharedmem));
	if ((*sm)==NULL) {
		printf("Failed to initialize shared memory. Bad pointer?\n");
		return -1;
	}
	(*sm)->memory = calloc(SHARED, sizeof(char*));
	(*sm)->semaphores = calloc(SHARED, sizeof(semaphore));
	for (i=0;i<SHARED;i++) {
		(*sm)->memory[i] = calloc(4, sizeof(char));
		memcpy((*sm)->memory[i] , temp, 4);
		((*sm)->semaphores[i]).value = 1;
		((*sm)->semaphores[i]).owner = 0;
		queueInit(&((*sm)->semaphores[i].que));
	}

	return 0;
}

int flush_share (sharedmem * sm) {
	if (sm==NULL) {
		printf("Failed to initialize shared memory. Bad pointer?\n");
		return -1;
	}
	int i;
	for (i=0;i<SHARED;i++) {
		free((sm)->memory[i]);
		free((sm)->semaphores[i].que);
		free(&(sm)->semaphores[i]);
	}
	free((sm)->memory);
	return 0;
}

int store_share(sharedmem * sm, int location, char * value) {
	if (sm==NULL) {
		printf("Uninitialized shared memory. Bad pointer?\n");
		return -1;
	}
	if (location>=SHARED) {
		printf("Outside memory.\n");
		return -1;
	}
	memcpy(sm->memory[location], value, 4);
	return 0;
}

int load_share(sharedmem * sm, int location, char * value) {
	if (sm==NULL) {
		printf("Uninitialized shared memory. Bad pointer?\n");
		return -1;
	}
	if (location>=SHARED) {
		printf("Outside memory.\n");
		return -1;
	}
	memcpy(value, sm->memory[location], 4);
	return 0;
}

/*
 *
 * Semaphore Stuff
 *
 * */


int _p(sharedmem * sm, int index, int id) {
	if (index>=SHARED) {
		printf("Outside memory.\n");
		return -1;
	}
	if ((sm->semaphores[index]).value>0)
		(sm->semaphores[index]).value--;
	else {
		enqueue(sm->semaphores[index].que, id);
		return -1;
	}
	return 0;
}

int _v(sharedmem * sm, int index) {
	if (index>=SHARED) {
		printf("Outside memory.\n");
		return -1;
	}
	int x;
	x = dequeue(sm->semaphores[index].que);
	if (x==-1)
		(sm->semaphores[index]).value++;
	else {
		return x;
	}
	return 0;
}

int sema_init(sharedmem * sm, int index, int value) {
	if (index>=SHARED) {
		printf("Outside memory.\n");
		return -1;
	}
	(sm->semaphores[index]).value = value;
	return 0;
}


